package com.sskj.motherboard.handler;

import com.sskj.common.enums.DeviceMessageTypeEnum;
import com.sskj.motherboard.constant.ChannelAttributesConstant;
import com.sskj.motherboard.handler.strategy.FrameMessageHandlerFactory;
import com.sskj.motherboard.handler.strategy.IFrameMessageHandlerStrategy;
import com.sskj.motherboard.server.ClientManager;
import com.sskj.motherboard.util.StrUtil;
import com.sskj.motherboard.vo.FrameMessage;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FrameMessageHandler extends SimpleChannelInboundHandler<FrameMessage> {

    private final FrameMessageHandlerFactory factory;

    public FrameMessageHandler(FrameMessageHandlerFactory factory) {
        this.factory = factory;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FrameMessage frameMessage) throws Exception {
        handleFrameMessage(channelHandlerContext, frameMessage);
    }

    private void handleFrameMessage(ChannelHandlerContext channelHandlerContext, FrameMessage frameMessage) {
        Integer messageType = getMessageType(frameMessage);
        if (messageType != null) {
            IFrameMessageHandlerStrategy handler = this.factory.getHandler(messageType);
            if (handler != null) {
                handler.handle(channelHandlerContext, frameMessage);
            } else {
                log.warn("未找到对应的处理类,命令码:{}", StrUtil.toHexStr(frameMessage.getCommandCode()));
            }
        } else {
            log.warn("未找到对应的消息类型,设备信息:{}", frameMessage);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端已断开: {}", ctx.channel().remoteAddress());
        IFrameMessageHandlerStrategy handler = this.factory.getHandler(DeviceMessageTypeEnum.OFFLINE.getType());
        if (handler != null) {
            handler.handle(ctx, null);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("连接异常", cause);
        ctx.close();
    }

    // 获取消息类型
    private Integer getMessageType(FrameMessage frameMessage) {
        if (frameMessage != null) {
            if (frameMessage.getCommandType() == 0x01 && frameMessage.getCommandCode() == 0x02) {
                return DeviceMessageTypeEnum.REGISTER.getType();
            }
            if (frameMessage.getCommandType() == 0x01 && frameMessage.getCommandCode() == 0x01) {
                return DeviceMessageTypeEnum.HEARTBEAT_CHECK.getType();
            }
        }
        return null;
    }
}
